home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Snippets / QuickDraw / Snapshot / Snapshot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-15  |  6.6 KB  |  224 lines  |  [TEXT/KAHL]

  1. /****************************************************************************/
  2. /*                                                                            */
  3. /*    Application:    Snapshot                                                */
  4. /*                                                                            */
  5. /*    Description:    This application demonstrates how to quickly and        */
  6. /*                    efficiently capture the main device's desktop into        */
  7. /*                    a window.  The program basically reads the image         */
  8. /*                    stored in the the main device's pixmap then copies        */
  9. /*                    it to a custom pixmap.  The custom pixmap is de-        */
  10. /*                    fined at the same depth of the main device and             */
  11. /*                    contains an identical copy of that device's color-        */
  12. /*                    table.  This is done to provide the fastest             */
  13. /*                    performance possible when copying from an offscreen        */
  14. /*                     to onscreen pixmap.  By making sure the pixel values    */
  15. /*                     map to the exact same colors in both colortables,        */
  16. /*                     copybits will do a direct transfer of bits without        */
  17. /*                     wasting time remapping the colors.  Also the ctSeed        */
  18. /*                     field for each colortable should be the same.  Finally,    */
  19. /*                     since the main device's bounding rect is different        */
  20. /*                     than that of the offscreen's, the copying performance    */
  21. /*                     for the device to the offscreen is slightly affected    */
  22. /*                     because of the scaling required.  However, the copying    */
  23. /*                     performance for the offscreen to the window is the         */
  24. /*                     best possible since the bounding rects for each are        */
  25. /*                     identical.                                                */
  26. /*                                                                            */
  27. /*    File:            Snapshot.c                                                */
  28. /*                                                                            */
  29. /*    Programmer:        Edgar Lee                                                */
  30. /*    Organization:    Apple Computer, Inc.                                    */
  31. /*    Department:        Developer Technical Support, DTS                        */
  32. /*    Language:        C (Think C version 4.0.4)                                */
  33. /*    Date Created:    10-04-91                                                */
  34. /*                                                                            */
  35. /****************************************************************************/
  36.  
  37. #include <AppleEvents.h>
  38. #include <Errors.h>
  39. #include <Events.h>
  40. #include <Fonts.h>
  41. #include <GestaltEqu.h>
  42. #include <Memory.h>
  43. #include <Menus.h>
  44. #include <OSUtils.h>
  45. #include <QDOffscreen.h>
  46. #include <QuickDraw.h>
  47. #include <Resources.h>
  48. #include <Script.h>
  49. #include <ToolUtils.h>
  50. #include <Windows.h>
  51.  
  52. /* Constant Declarations */
  53.  
  54. #define    WWIDTH        ((screenBits.bounds.right - screenBits.bounds.left) / 2)
  55. #define    WHEIGHT        ((screenBits.bounds.bottom - screenBits.bounds.top) / 2)
  56.  
  57. #define WLEFT        (((screenBits.bounds.right - screenBits.bounds.left) - WWIDTH) / 2)
  58. #define WTOP        (((screenBits.bounds.bottom - screenBits.bounds.top) - WHEIGHT) / 2)
  59.  
  60. /* Global Variable Definitions */
  61.  
  62. WindowPtr    gWindow;            /* Main window */
  63. PixMap        gPixMap;            /* Offscreen pixmap */
  64. Rect        gBounds;            /* Offscreen pixmap's bounding rect */
  65.  
  66. void initMac();
  67.  
  68. void createWindow();
  69.  
  70. void initPixmap();
  71. void createImage();
  72. void drawImage();
  73.  
  74. void doEventLoop();
  75.  
  76. main()
  77. {
  78.     initMac();
  79.     
  80.     createWindow();                /* Create a window to display the final image. */
  81.     
  82.     initPixmap();                /* Initialize offscreen pixmap. */
  83.     createImage();                /* Copy the main screen's pixmap into the offscreen's. */
  84.     drawImage();                /* Copy the offscreen's pixmap onto the window. */
  85.  
  86.     doEventLoop();                /* Handle any events. */
  87.     
  88.     DisposPixMap( &gPixMap );    /* Clean up the memory allocated for the pixmap. */
  89.     DisposeWindow( gWindow );
  90. }
  91.  
  92. void initMac()
  93. {
  94.     MaxApplZone();
  95.     
  96.     InitGraf( &thePort );
  97.     InitFonts();
  98.     InitWindows();
  99.     InitMenus();
  100.     TEInit();
  101.     InitDialogs( nil );
  102.     InitCursor();
  103.     FlushEvents( 0, everyEvent );    
  104. }
  105.  
  106. void createWindow()
  107. {
  108.     Rect wBounds;
  109.     
  110.     /* Create a window to display the final offscreen image. */
  111.     
  112.     SetRect( &wBounds, WLEFT, WTOP, WLEFT + WWIDTH, WTOP + WHEIGHT );
  113.     
  114.     gWindow = NewCWindow( 0L, &wBounds, "\pSnapshot Test", false, documentProc,
  115.                             (WindowPtr)-1L, true, 0L );
  116.                             
  117.     SetRect( &gBounds, 0, 0, gWindow->portRect.right - gWindow->portRect.left,
  118.                     gWindow->portRect.bottom - gWindow->portRect.top );
  119.                             
  120.     SetPort( gWindow );
  121. }
  122.  
  123. void initPixmap()
  124. {
  125.     Ptr            offBaseAddr;    /* Pointer to the off-screen pixel image */
  126.     short        bytesPerRow;
  127.     GDHandle    mainDevice;
  128.     CTabHandle    cTable;
  129.     short        depth;
  130.  
  131.     /* Get a handle to the main device. */
  132.     mainDevice = GetMainDevice();
  133.  
  134.     /* Store its current pixel depth. */
  135.     depth = (**(**mainDevice).gdPMap).pixelSize;
  136.  
  137.     /* Make an identical copy of its pixmap's colortable. */
  138.     cTable = (**(**mainDevice).gdPMap).pmTable;
  139.     HandToHand( &cTable );
  140.  
  141.     bytesPerRow = ((gBounds.right - gBounds.left) * depth) / 8;
  142.     offBaseAddr = NewPtr((unsigned long)bytesPerRow * (gBounds.bottom - gBounds.top));
  143.     
  144.     gPixMap.baseAddr = offBaseAddr;              /* Point to image */
  145.     gPixMap.rowBytes = bytesPerRow | 0x8000;    /* MSB set for PixMap */
  146.     gPixMap.bounds = gBounds;                     /* Use given bounds */
  147.     gPixMap.pmVersion = 0;                       /* No special stuff */
  148.     gPixMap.packType = 0;                        /* Default PICT pack */
  149.     gPixMap.packSize = 0;                        /* Always zero in mem */
  150.     gPixMap.hRes = 72;                          /* 72 DPI default res */
  151.     gPixMap.vRes = 72;                          /* 72 DPI default res */
  152.     gPixMap.pixelSize = depth;                   /* Set # bits/pixel */
  153.     gPixMap.planeBytes = 0;                      /* Not used */
  154.     gPixMap.pmReserved = 0;                      /* Not used */
  155.  
  156.     gPixMap.pixelType = 0;                       /* Indicates indexed */
  157.     gPixMap.cmpCount = 1;                        /* Have 1 component */
  158.     gPixMap.cmpSize = depth;                     /* Component size=depth */
  159.     gPixMap.pmTable = cTable;                     /* Handle to CLUT */
  160. }
  161.  
  162. void createImage()
  163. {
  164.     GDHandle    mainDevice;
  165.  
  166.     mainDevice = GetMainDevice();
  167.  
  168.     /* Store the screen's pixmap image in the offscreen pixmap. */
  169.  
  170.     CopyBits( *(**mainDevice).gdPMap, (BitMap *)(&gPixMap),
  171.                 &(**(**mainDevice).gdPMap).bounds, &gPixMap.bounds, srcCopy, 0l );
  172. }
  173.  
  174. void drawImage()
  175. {
  176.     /* Copy the offscreen image back onto the window. */
  177.  
  178.     CopyBits( (BitMap *)&gPixMap, &gWindow->portBits, &gPixMap.bounds,
  179.                 &gWindow->portRect, srcCopy, 0l);
  180.                 
  181.     ShowWindow( gWindow );
  182. }
  183.  
  184. void doEventLoop()
  185. {
  186.     EventRecord anEvent;
  187.     WindowPtr   evtWind;
  188.     short       clickArea;
  189.     Rect        screenRect;
  190.  
  191.     for (;;)
  192.     {
  193.         if (WaitNextEvent( everyEvent, &anEvent, 0, nil ))
  194.         {
  195.             if (anEvent.what == mouseDown)
  196.             {
  197.                 clickArea = FindWindow( anEvent.where, &evtWind );
  198.                 
  199.                 if (clickArea == inDrag)
  200.                 {
  201.                     screenRect = (**GetGrayRgn ()).rgnBBox;
  202.                     DragWindow( evtWind, anEvent.where, &screenRect );
  203.                 }
  204.                 else if (clickArea == inContent)
  205.                 {
  206.                     if (evtWind != FrontWindow())
  207.                         SelectWindow( evtWind );
  208.                 }
  209.                 else if (clickArea == inGoAway)
  210.                     if (TrackGoAway( evtWind, anEvent.where ))
  211.                         return;
  212.             }
  213.             else if (anEvent.what == updateEvt)
  214.             {
  215.                 evtWind = (WindowPtr)anEvent.message;    
  216.                 SetPort( evtWind );
  217.                 
  218.                 BeginUpdate( evtWind );
  219.                 drawImage();
  220.                 EndUpdate (evtWind);
  221.             }
  222.         }
  223.     }
  224. }